/*
 * NETMAJ - network mahjongg -  Copyright Notice
 *     Copyright (C) 1994, 1995, 1996 Koji Suzuki (suz@kt.rim.or.jp)
 *
 *  You can redistribute it and/or modify this software under the terms 
 * of the GNU General Public License version 2 as published by
 * the Free Software Foundation.
 *
 *  This software is provided 'as-is', without any express or implied
 * warranty.  In no event will the author be held liable for any damages
 * arising from the use of this software.
 * See the gpl.text for more details.
 *
 *  If you would like to do something with NETMAJ that this copyright
 * prohibits (such as distributing it with a commercial product,
 * using portions of the source in some other program, etc.), please
 * contact the author (preferably via email).  Arrangements can
 * probably be worked out.
 *
 *  Koji Suzuki   : suz@kt.rim.or.jp
 */
/* $Id: thread.c,v 1.6 1996/07/31 08:06:27 suz Exp $ */

#include <pthread.h>
#include "port.h"
#include <signal.h>
#include "pai.h"
#include "global.h"

char *msgGets();

server_thread(gp) global_t *gp;
{
	game(gp);
}

talk(gp,from,msg) global_t *gp; char *msg; {
}

fatal() {
fprintf(stderr,"fatal\n");
exit(1);
}

auto_thread(gp) global_t *gp;
{
	char buf[MSG_MAX];
	int st,c;
	int res,how;

	analize_init(gp);

	while (msgGets(gp,buf,sizeof(buf)-1,4)) {
		st = recv_message(gp,buf);
		switch(st) {
		case ACT_RES:
			res = analize_res(gp,&how);
			sprintf(buf,MSG_REPL,res,how);
			msgWrites(gp,buf,4);
			break;
		case ACT_SEL:
			analize(gp,vself);
			sprintf(buf,MSG_ASK,ask_attr,ask_pai);
			msgWrites(gp,buf,4);
			break;
		case ACT_PEND:
			pf_pend(gp);
			break;
		case ACT_GEND:
			pf_gend(gp);
			pf_term(gp);
			pthread_exit(0);
			break;
		case ACT_COMMENT:
			break;
		}
	}
}


global_t *globals[5];
port_t port[5];
pthread_t pthreads[4];

FILE *df;

main(argc,argv) int argc; char *argv[]; {
	int i,c,j;
	int dmy;
	pthread_attr_t attr;
	char *names[4];

	srandom(time(0));
	pthread_init();
#if 0
	df = stderr;
#endif
	for (i=1; i<argc && i<=4; i++) {
		names[i-1] = argv[i];
	}
	for (; i<=4; i++) {
		names[i-1] = "auto";
	}

	for (i=0; i<5; i++) {
		globals[i] = global_alloc();
	}
	for (i=0; i<4; i++) {
		globals[i]->_self = i;
		for (j=0; j<5; j++) {
			strcpy(globals[j]->_player[i].name,names[i]);
			globals[j]->_player[i].flags = 0;
		}
		pf_init(globals[i],globals[i]->_player[i].name,argv[0]);
	}
	for (i=0; i<5; i++) 
		port_init(port+i,0,0);

	attr = pthread_attr_default;
	pthread_attr_setstacksize(&attr,160000);

	pthread_create(pthreads+0,attr,auto_thread,globals[0]);
	pthread_create(pthreads+1,attr,auto_thread,globals[1]);
	pthread_create(pthreads+2,attr,auto_thread,globals[2]);
	pthread_create(pthreads+3,attr,auto_thread,globals[3]);
	server_thread(globals[4]);

	for (i=0; i<4; i++)
		pthread_join(pthreads[i],&dmy);
		pthread_detach(pthreads+i);
}

int msgWrites(gp,buf,p) global_t *gp; char *buf; int p; {
	int port_id,i,q,len,ret;
	char msg[256];

	len = strlen(buf)+1;

	q = 4;
	port_id = p;
	if (p==4) {
		for (i = 0; i<4; i++)
			if (gp == globals[i])
				q = i;
	}


	sprintf(msg,"%c%03d%s",q,len,buf);
	ret = port_write(port+port_id,msg,len+4);
	return (ret>=0)?(ret-4):ret ;
}

static char readable[5] = {-1,-1,-1,-1,-1};

msgSelect(gp,time_out) global_t *gp; int time_out; {
	if (readable[4] < 0)
		port_read(port+4,readable+4,1);
	return 1;
}

msgIsRead(gp,p) global_t *gp; {
	return (readable[4] == p);
}

char *msgGets(gp,buf,len,p) global_t *gp; char *buf; int len; int p; {
	int i;
	int port_id,len;
	int ret=0;
	char msg[3];

	port_id = 4;
	if (p==4) {
		for (i = 0; i<4; i++)
			if (gp == globals[i])
				port_id = i;
	}

	if (readable[port_id] < 0)
			port_read(port+port_id,readable+port_id,1);


	if (readable[port_id] == p) {
		port_read(port+port_id,msg,3);
		len = (msg[0] - '0')* 100 + (msg[1] - '0') * 10 + msg[2] - '0';
		ret = port_read(port+port_id,buf,len);
		readable[port_id] = -1;
	}
	return (ret>0)?buf:0;
}
